// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility that Flutter provides. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.

import 'dart:io';

import 'package:crypto/crypto.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mybase/base/tool/empty/FFEmpty.dart';
import 'package:mybase/base/tool/entitylog/MyEntityTestRun.dart';
import 'package:mybase/base/tool/entitylog/MyLanguageTestRun.dart';
import 'package:mybase/base/tool/file/FFile.dart';
import 'package:mybase/base/tool/globalMethod/FFSafeValue.dart';
import 'dart:convert';

import 'package:mybase/base/tool/pprint/FFLog.dart';

///运行前请先格式化目标文件
Future<void> main() async {
  String languageValueFilePath =
      "/Users/os/led138/lib/config/value/LanguageValue.dart";

  int startLine = 1541; //从0开始算
  int endLine = 1559; //从0开始算

  // true ,打印出指定的key value;
  // false ,修改LanguageValue文件
  if (false) {
    await languageValueToMapKeyValues(languageValueFilePath, startLine, endLine);
  }  else {
    await languageValueOverride(languageValueFilePath, startLine, endLine);
  }
}

///startLine 从0开始算
Future<void> languageValueOverride(String languageValueFilePath, int startLine, int endLine) async {

  List<TestMethodEntity>? entitys = await languageValueToMapKeyValues(languageValueFilePath, startLine, endLine);

  if (FFEmpty.listIsEmpty(entitys)) {
    FFLog.error("entitys为空");
    return;
  }

  List<String>? lines = await FFile.readByLine(
    languageValueFilePath,
    isTrim: true,
  );

  if (FFEmpty.listIsEmpty(lines)) {
    FFLog.error("lines为空");
    return;
  }

  for (int i = 0; i < entitys!.length; i++) {
    TestMethodEntity entity = entitys![i];
    String oldLine = lines![entity.line];
    // if (entity.hasStaticString == true) {
    //   lines![entity.line] = "${entity.changeBodyLine!.substring(0,entity.changeBodyLine!.length - 1)}??\"\";";
    // }  else {
    //   lines![entity.line] = entity.changeBodyLine!;
    // }

    lines![entity.line] = entity.changeBodyLine!;
  }

  //准备覆盖
  String content = "";
  for (int i = 0; i < lines!.length; i++) {
      content = "${content}\n${lines![i]}";
  }
  bool success = await FFile.writeContentByPath(filePath: languageValueFilePath, content: content,mode: FileMode.write);
  if (success) {
    print("Override成功");
  }  else {
    print("Override失败");
  }


}

///从LanguageValue.dart生成键值对
///startLine 从0开始算
Future<List<TestMethodEntity>?> languageValueToMapKeyValues(
  String languageValueFilePath,
  int startLine,
  int endLine, {
  bool? printKeyValues = true,
}) async {
  List<TestMethodEntity> entitys = [];
  //文件是否存在
  bool exists = await FFile.isExistFile(languageValueFilePath);
  if (exists == false) {
    FFLog.error("文件不存在 ${languageValueFilePath}");
    return entitys;
  }

  List<String>? lines = await FFile.readByLine(
    languageValueFilePath,
    isTrim: true,
    startLine: startLine,
    endLine: endLine,
  );
  if (FFEmpty.listIsEmpty(lines)) {
    FFLog.error("没有读取到数据");
    return entitys;
  }

  bool error = false;

  for (int i = 0; i < lines!.length; i += 4) {
    TestMethodEntity entity = TestMethodEntity(
        methosNameLine: lines[i],
        bodyLine: lines[i + 1],
        endLine: lines[i + 2],
        line: i + startLine + 1);
    bool success = entity.checkValid();
    if (success == false) {
      error = true;
      break;
    }

    entitys.add(entity);
  }

  if (error) {
    FFLog.error("出错了,请检查是否有格式化，一个方法最多三行");
    return entitys;
  }

  if (printKeyValues == true) {
    for (int i = 0; i < entitys.length; i++) {
      TestMethodEntity entity = entitys[i];
      print('"${entity.getMethodName()}":${entity.getBodyStr()},');
    }
  }
  return entitys;
}

class TestMethodEntity {
  String methosNameLine;
  String bodyLine;
  String endLine;
  int line;
  String? changeBodyLine;
  bool? hasStaticString;
  bool? hasFormat;

  TestMethodEntity({
    required this.methosNameLine,
    required this.bodyLine,
    required this.endLine,
    required this.line,
    this.changeBodyLine,
    this.hasStaticString,
    this.hasFormat,
  });

  String getMethodName() {
    hasStaticString = methosNameLine.startsWith("static String");

    String eName = methosNameLine.split("static ")[1].split("(").first;
    if (eName.contains(" ")) {
      eName = eName.split(" ").last;
    }
    return eName;
  }

  String getBodyStr() {
    hasFormat = bodyLine.contains(".format(") && bodyLine.endsWith(");");

    String bodyStr = bodyLine.split("return ")[1];

    if (bodyStr.endsWith(");")) {
      if (bodyStr.contains(".format(")) {
        bodyStr = bodyStr.split(".format(").first;
      }
    } else {
      bodyStr = bodyStr.substring(0, bodyStr.length - 1);
    }

    if (hasStaticString == true) {
      if (hasFormat == true) {
        changeBodyLine = bodyLine.replaceAll(bodyStr, "AppLocale.of(context)?.language?.auto?.${getMethodName()}?");
        changeBodyLine = "${changeBodyLine!.substring(0,changeBodyLine!.length - 1)} ?? \"\"; ";
      }  else {
        changeBodyLine = bodyLine.replaceAll(bodyStr, "AppLocale.of(context)?.language?.auto?.${getMethodName()}??\"\"");
      }

    }  else {
      if (hasFormat == true) {
        changeBodyLine = bodyLine.replaceAll(bodyStr, "AppLocale.of(context)?.language?.auto?.${getMethodName()}?");
        changeBodyLine = "${changeBodyLine!.substring(0,changeBodyLine!.length - 1)} ?? \"\"; ";
      }  else {
        changeBodyLine = bodyLine.replaceAll(bodyStr, "AppLocale.of(context)?.language?.auto?.${getMethodName()}");
      }

    }


    return bodyStr;
  }

  bool checkValid() {
    if (FFEmpty.stringIsEmpty(methosNameLine) ||
        FFEmpty.stringIsEmpty(bodyLine) ||
        FFEmpty.stringIsEmpty(endLine)) {
      return false;
    }

    if (!methosNameLine.startsWith("static")) {
      return false;
    }

    if (!bodyLine.startsWith("return")) {
      return false;
    }

    if (endLine != "}") {
      return false;
    }

    return true;
  }
}
